#include "TestNewArbol.h"

#include "../src/indices/Elemento.h"
#include "../src/indices/arbol/Arbol.h"

TestNewArbol::TestNewArbol() {
	elements[0] = new Elemento(Key(new ClaveInt(5)), 5);
	elements[1] = new Elemento(Key(new ClaveInt(8)), 8);
	elements[2] = new Elemento(Key(new ClaveInt(1)), 1);
	elements[3] = new Elemento(Key(new ClaveInt(3)), 3);
	elements[4] = new Elemento(Key(new ClaveInt(10)), 10);
	elements[5] = new Elemento(Key(new ClaveInt(2)), 2);
	elements[6] = new Elemento(Key(new ClaveInt(9)), 9);
	elements[7] = new Elemento(Key(new ClaveInt(11)), 11);
	elements[8] = new Elemento(Key(new ClaveInt(17)), 17);
	elements[9] = new Elemento(Key(new ClaveInt(4)), 4);
	elements[10] = new Elemento(Key(new ClaveInt(0)), 0);
	elements[11] = new Elemento(Key(new ClaveInt(19)), 19);
	elements[12] = new Elemento(Key(new ClaveInt(20)), 20);
	elements[13] = new Elemento(Key(new ClaveInt(21)), 21);
	elements[14] = new Elemento(Key(new ClaveInt(27)), 27);
	elements[15] = new Elemento(Key(new ClaveInt(43)), 43);
	elements[16] = new Elemento(Key(new ClaveInt(45)), 45);
	elements[17] = new Elemento(Key(new ClaveInt(29)), 29);
	elements[18] = new Elemento(Key(new ClaveInt(23)), 23);
	elements[19] = new Elemento(Key(new ClaveInt(7)), 7);
	elements[20] = new Elemento(Key(new ClaveInt(31)), 31);
	elements[21] = new Elemento(Key(new ClaveInt(40)), 40);
	elements[22] = new Elemento(Key(new ClaveInt(25)), 25);
	for (int i = 0; i < 100; i++) {
		clavesOrdenadas[i] = new Key(new ClaveInt(i));
	}

}

TestNewArbol::~TestNewArbol() {
	for (int i = 0; i < 23; ++i) {
		delete elements[i];
	}

}

void TestNewArbol::run() {

	claveOK();
	claveInexistente();
	claveDuplicada();
	Vaciar();
	Inicio();
	ExplotaRaiz();
	borrarBasico();
	borrarBasico2();
	borrarClaveEstaEnPadreQueEsRaiz();
	underBalanceo();
	mergeDerechoHoja();
	mergeDerechoIzqHoja();
	mergeDerDerHoja();
	dosNoMergean();
	borrarTerminos();

}

void TestNewArbol::borrarTerminos() {

	system("rm -r -f ./ArbolPruebas/Arbolborr*");
	Arbol arbol("./ArbolPruebas/Arbolborr", &extractor, 4, 4);
	for (int i = 0; i < 100; ++i) {
		Elemento elemento(Key(new ClaveInt(i)), i);
		arbol.insertar(elemento);
	}
	std::cout << " El arbol con las 100 claves "
	<< "------------------------------ " << std::endl;

	arbol.visualizar();
	for (int i = 0; i < 97; ++i) {
		Elemento elemento(Key(new ClaveInt(i)), i);
		arbol.borrar(elemento);
		std::cout << "borré el elemento " << i
				<< "------------ y el arbol quedó:" << std::endl;
		arbol.visualizar();

	}
}

void TestNewArbol::claveOK() {
	system("rm -r -f ./ArbolPruebas/ArbolclaveOK*");
	Arbol arbol("./ArbolPruebas/ArbolclaveOK", &extractor, 4, 4);
	std::cout << "-------------------------clave ok------------------------"
			<< std::endl;

	Resultado res;
	for (int i = 0; i < 23; ++i) {
		res = arbol.insertar(*elements[i]);
		assert(res == 0, "claves insertadas correctamente");
	}
}
void TestNewArbol::claveInexistente() {
	system("rm -r -f ./ArbolPruebas/ArbolclaveInex*");
	Arbol arbol("./ArbolPruebas/ArbolclaveInex", &extractor, 4, 4);
	std::cout
			<< "-------------------------clave inexistente------------------------"
			<< std::endl;

	Resultado res;
	for (int i = 0; i < 11; ++i) {
		arbol.insertar(*elements[i]);
	}
	Elemento elem(Key(new ClaveInt(60)), 60);
	res = arbol.borrar(elem);
	assert(res == 2, "clave insertada era inexistente");
	Elemento elem2(Key(new ClaveInt(34)), 34);
	res = arbol.borrar(elem2);
	assert(res == 2, "clave insertada era inexistente");
	Elemento elem3(Key(new ClaveInt(22)), 22);
	res = arbol.borrar(elem3);
	assert(res == 2, "clave insertada era inexistente");
	res = arbol.borrar(elem);
	assert(res == 2, "clave insertada era inexistente");

}
void TestNewArbol::claveDuplicada() {
	system("rm -r -f ./ArbolPruebas/ArbolclaveDuplicada*");
	Arbol arbol("./ArbolPruebas/ArbolclaveDuplicada", &extractor, 3, 4);
	std::cout
			<< "-------------------------clave duplicada------------------------"
			<< std::endl;

	Resultado res;
	for (int i = 0; i < 8; ++i) {
		arbol.insertar(*elements[i]);
	}
	Elemento elem(Key(new ClaveInt(8)), 8);
	res = arbol.insertar(elem);
	assert(res == 1, "clave insertada era duplicada");
	Elemento elem2(Key(new ClaveInt(5)), 5);
	res = arbol.insertar(elem2);
	assert(res == 1, "clave insertada era duplicada");
	Elemento elem3(Key(new ClaveInt(9)), 9);
	res = arbol.insertar(elem3);
	assert(res == 1, "clave insertada era duplicada");
}

void TestNewArbol::Vaciar() {
	system("rm -r -f ./ArbolPruebas/ArbolVaciar*");
	Arbol arbol("./ArbolPruebas/ArbolVaciar", &extractor, 4, 4);

	std::cout
			<< "---------------------------inserto y borro y esta vacío--------------------------"
			<< std::endl;

	for (int i = 0; i < 3; ++i) {
		arbol.insertar(*elements[i]);
	}
	for (int i = 0; i < 3; i++) {
		arbol.borrar(*elements[i]);
	}
	assert(arbol.getRaiz() == NULL, "el arbol está vacio");
}

void TestNewArbol::Inicio() {
	std::cout
			<< "---------------------------nuevo arbol y esta vacío--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/Arbolinicio*");
	Arbol arbol("./ArbolPruebas/Arbolinicio", &extractor, 4, 4);
	assert(arbol.getCantClavesMax() == 3, "el tiene la cant max setiada bien");
	assert(arbol.getRaiz() == NULL, "el arbol está vacio");

}

void TestNewArbol::ExplotaRaiz() {
	system("rm -r -f ./ArbolPruebas/ArbolExplotaRaiz*");
	Arbol arbol("./ArbolPruebas/ArbolExplotaRaiz", &extractor, 4, 4);
	std::cout
			<< "-------------------------explota raiz------------------------"
			<< std::endl;

	Resultado res;
	for (int i = 0; i < 6; ++i) {
		res = arbol.insertar(*elements[i]);
	}
	assert(arbol.getRaiz()->getId() == ID_RAIZ, "la raiz tiene ID_RAIZ ");
	assert(arbol.getRaiz()->getPadre() == ID_NULL, "la raiz tiene ID_NULL ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[0]
			== *clavesOrdenadas[1], "el arbol debería tener en el nodo 01: 1 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[1]
			== *clavesOrdenadas[2], "el arbol debería tener en el nodo 01: 2 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[0]
			== *clavesOrdenadas[3], "el arbol debería tener en el nodo 02: 3 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[1]
			== *clavesOrdenadas[5], "el arbol debería tener en el nodo 02: 5 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[0]
			== *clavesOrdenadas[8], "el arbol debería tener en el nodo 03: 8");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[1]
			== *clavesOrdenadas[10],
			"el arbol debería tener en el nodo 03: 10 ");

	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[2],
			"el arbol debería tener en la raíz 2");
	assert(arbol.getRaiz()->getClaves()[1] == *clavesOrdenadas[5],
			"el arbol debería tener en la raíz 5 ");
}

void TestNewArbol::AgregoAIntRaiz() {
	system("rm -r -f ./ArbolPruebas/ArbolAgregoAIntRaiz*");
	Arbol arbol("./ArbolPruebas/ArbolAgregoAIntRaiz", &extractor, 4, 4);
	std::cout
			<< "-------------------------AgregoAInterno que es Raiz------------------------"
			<< std::endl;

	Resultado res;
	for (int i = 0; i < 10; ++i) {
		res = arbol.insertar(*elements[i]);

	}
	assert(arbol.getRaiz()->getId() == ID_RAIZ, "la raiz tiene ID_RAIZ ");
	assert(arbol.getRaiz()->getPadre() == ID_NULL, "la raiz tiene ID_NULL ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[3])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[1]
			== arbol.getRaiz()->getClaves()[0],
			"el arbol debería tener en raiz: 2 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[2]
			== arbol.getRaiz()->getClaves()[1],
			"el arbol debería tener en raiz: 5 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[2]
			== arbol.getRaiz()->getClaves()[2],
			"el arbol debería tener en raiz: 10 ");

}

void TestNewArbol::BalanceoHojaIzq() {
	system("rm -r -f ./ArbolPruebas/ArbolBalanceoHojaIzq*");
	Arbol arbol("./ArbolPruebas/ArbolBalanceoHojaIzq", &extractor, 4, 4);
	std::cout
			<< "-------------------------BalanceoHojaIzq------------------------"
			<< std::endl;

	for (int i = 0; i < 6; ++i) {
		arbol.insertar(*elements[i]);
	}
	Elemento elemento(Key(new ClaveInt(19)), 19);

	Elemento elemento2(Key(new ClaveInt(20)), 20);
	arbol.insertar(elemento);
	arbol.insertar(elemento2);
	assert(arbol.getRaiz()->getClaves()[1] == *clavesOrdenadas[8],
			"el arbol debería tener en la raíz 8 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[2]
			== *clavesOrdenadas[8],
			"el arbol debería tener en hijo del medio mayor clave un 8 ");
}

void TestNewArbol::NoBalanceoHojaIzq() {
	system("rm -r -f ./ArbolPruebas/ArbolNOBalanceoHojaIzq*");
	Arbol arbol("./ArbolPruebas/ArbolNOBalanceoHojaIzq", &extractor, 4, 4);
	std::cout
			<< "-------------------------No Balanceo Hoja Izq, entonces creo otra hoja------------------------"
			<< std::endl;

	for (int i = 0; i < 6; ++i) {
		arbol.insertar(*elements[i]);
	}
	Elemento elemento(Key(new ClaveInt(19)), 19);

	Elemento elemento2(Key(new ClaveInt(20)), 20);
	arbol.insertar(elemento);
	arbol.insertar(elemento2);
	Elemento elemento3(Key(new ClaveInt(21)), 21);
	arbol.insertar(elemento3);
	assert(arbol.getRaiz()->getClaves()[2] == *clavesOrdenadas[19],
			"el arbol debería tener en la raíz 19 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[1]
			== *clavesOrdenadas[19],
			"el arbol debería tener en hijo tercero, un 19 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[3])->getClaves()[0]
			== *clavesOrdenadas[20],
			"el arbol debería tener en hijo mayor, un 20 ");
}

void TestNewArbol::BalanceoIntRaiz() {
	system("rm -r -f ./ArbolPruebas/ArbolBalanceoIntRaiz*");
	Arbol arbol("./ArbolPruebas/ArbolBalanceoIntRaiz", &extractor, 4, 4);
	std::cout
			<< "-------------------------over en raiz interna: balanceo con un nuevo hermano------------------------"
			<< std::endl;

	for (int i = 0; i < 15; ++i) {
		arbol.insertar(*elements[i]);
	}
	assert(arbol.getRaiz()->getId() == ID_RAIZ, "la raiz tiene ID_RAIZ ");
	assert(arbol.getRaiz()->getPadre() == ID_NULL, "la raiz tiene ID_NULL ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[3])->getClaves()[2]
			== arbol.getRaiz()->getClaves()[3],
			"el arbol debería tener en ela raiz el mas grande  de la primer rama ");

}

void TestNewArbol::InsertoInternoNORaiz() {
	system("rm -r -f ./ArbolPruebas/ArbolInsertoInternoNORaiz*");
	Arbol arbol("./ArbolPruebas/InsertoInternoNORaiz", &extractor, 4, 4);
	std::cout
			<< "-------------------------Inserto en nodo Interno NO Raiz-----------------------"
			<< std::endl;

	for (int i = 0; i < 18; ++i) {
		arbol.insertar(*elements[i]);
	}

	Elemento elemento(Key(new ClaveInt(22)), 22);

	Elemento elemento2(Key(new ClaveInt(23)), 23);
	arbol.insertar(elemento);
	arbol.insertar(elemento2);
	Elemento elemento3(Key(new ClaveInt(18)), 18);
	arbol.insertar(elemento3);

	assert(arbol.getRaiz()->getId() == ID_RAIZ, "la raiz tiene ID_RAIZ ");
	assert(arbol.getRaiz()->getPadre() == ID_NULL, "la raiz tiene ID_NULL ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(
			arbol.get(
					arbol.get(arbol.getRaiz()->getPunteros()[0])->getPunteros()[3])->getClaves()[2]
					== arbol.getRaiz()->getClaves()[0],
			"el arbol debería tener en ela raiz el mas grande  de la primer rama ");

}
void TestNewArbol::InsertoInternoNORaizNuevo() {
	system("rm -r -f ./ArbolPruebas/ArbolInsertoInternoNORaizNuevo*");
	Arbol arbol("./ArbolPruebas/InsertoInternoNORaizNuevo", &extractor, 4, 4);
	std::cout
			<< "-------------------------Inserto en nodo Interno NO Raiz y da overflow: nuevo interno-----------------------"
			<< std::endl;

	for (int i = 0; i < 18; ++i) {
		arbol.insertar(*elements[i]);
	}

	Elemento elemento(Key(new ClaveInt(22)), 22);
	Elemento elemento2(Key(new ClaveInt(23)), 23);
	arbol.insertar(elemento);
	arbol.insertar(elemento2);
	Elemento elemento3(Key(new ClaveInt(18)), 18);
	arbol.insertar(elemento3);

	Elemento elemento4(Key(new ClaveInt(42)), 42);
	arbol.insertar(elemento4);
	Elemento elemento5(Key(new ClaveInt(44)), 44);
	arbol.insertar(elemento5);

	assert(arbol.getRaiz()->getId() == ID_RAIZ, "la raiz tiene ID_RAIZ ");
	assert(arbol.getRaiz()->getPadre() == ID_NULL, "la raiz tiene ID_NULL ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getPadre() == ID_RAIZ,
			"el hijo de raiz apunta a su padre");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[0]
			== *clavesOrdenadas[2], "el arbol debería tener en el nodo 01: 1 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[1]
			== *clavesOrdenadas[5], "el arbol debería tener en el nodo 01: 5 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[0]
			== *clavesOrdenadas[18], "el arbol debería tener en el nodo 02:18 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[1]
			== *clavesOrdenadas[20],
			"el arbol debería tener en el nodo 02: 20 ");

	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[0]
			== *clavesOrdenadas[29], "el arbol debería tener en el nodo 03: 29");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[1]
			== *clavesOrdenadas[43],
			"el arbol debería tener en el nodo 03: 43 ");

	assert(
			arbol.getRaiz()->getClaves()[0]
					== arbol.get(
							arbol.get(arbol.getRaiz()->getPunteros()[0])->getPunteros()[2])->getClaves()[2],
			"el arbol debería tener en la raíz 10");
	assert(
			arbol.getRaiz()->getClaves()[1]
					== arbol.get(
							arbol.get(arbol.getRaiz()->getPunteros()[1])->getPunteros()[2])->getClaves()[1],
			"el arbol debería tener en la raíz 22");

}

void TestNewArbol::insertarOrdenado() {
	std::cout
			<< "---------------------------insertar ordenado--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolOrdenado*");
	Arbol arbol("./ArbolPruebas/ArbolOrdenado", &extractor, 4, 4);

	Elemento* elements[24];
	elements[0] = new Elemento(Key(new ClaveInt(0)), 0);
	elements[1] = new Elemento(Key(new ClaveInt(1)), 1);
	elements[2] = new Elemento(Key(new ClaveInt(2)), 2);
	elements[3] = new Elemento(Key(new ClaveInt(3)), 3);
	elements[4] = new Elemento(Key(new ClaveInt(4)), 4);
	elements[5] = new Elemento(Key(new ClaveInt(5)), 5);
	elements[6] = new Elemento(Key(new ClaveInt(7)), 7);
	elements[7] = new Elemento(Key(new ClaveInt(8)), 8);
	elements[8] = new Elemento(Key(new ClaveInt(9)), 9);
	elements[9] = new Elemento(Key(new ClaveInt(10)), 10);
	elements[10] = new Elemento(Key(new ClaveInt(11)), 11);
	elements[11] = new Elemento(Key(new ClaveInt(17)), 17);
	elements[12] = new Elemento(Key(new ClaveInt(19)), 19);
	elements[13] = new Elemento(Key(new ClaveInt(20)), 20);
	elements[14] = new Elemento(Key(new ClaveInt(21)), 21);
	elements[15] = new Elemento(Key(new ClaveInt(23)), 23);
	elements[16] = new Elemento(Key(new ClaveInt(25)), 25);
	elements[17] = new Elemento(Key(new ClaveInt(27)), 27);
	elements[18] = new Elemento(Key(new ClaveInt(29)), 29);
	elements[19] = new Elemento(Key(new ClaveInt(31)), 31);
	elements[20] = new Elemento(Key(new ClaveInt(40)), 40);
	elements[21] = new Elemento(Key(new ClaveInt(43)), 43);
	elements[22] = new Elemento(Key(new ClaveInt(45)), 45);

	for (int i = 0; i < 23; ++i) {
		arbol.insertar(*elements[i]);

	}
	for (int i = 0; i < 23; ++i) {
		delete elements[i];
	}
}

void TestNewArbol::borrarBasico() {

	system("rm -r -f ./ArbolPruebas/Arbolborrarbasico*");
	Arbol arbol("./ArbolPruebas/Arbolborrarbasico", &extractor, 4, 4);
	std::cout
			<< "---------------------------borrar basico--------------------------"
			<< std::endl;
	for (int i = 0; i < 2; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[0]);
	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[8],
			"el arbol debería tener en el nodo 0: 8 ");

}

void TestNewArbol::borrarBasico2() {
	std::cout
			<< "---------------------------borrar basico 2: borro clave que está en mi padre--------------------------"
			<< std::endl;

	system("rm -r -f ./ArbolPruebas/ArbolborrarBasico2*");
	Arbol arbol("./ArbolPruebas/ArbolborrarBasico2", &extractor, 4, 4);
	for (int i = 0; i < 7; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.insertar(*elements[10]);
	arbol.borrar(*elements[5]);
	assert(arbol.get(arbol.getRaiz()->getPunteros()[0])->getClaves()[1]
			== arbol.getRaiz()->getClaves()[0], "tiene el mayor del menor");
}

void TestNewArbol::borrarClaveEstaEnPadreQueEsRaiz() {
	std::cout
			<< "---------------------------borrar clave q esta en padre (raiz) pero son tres niveles --------------------------"
			<< std::endl;

	system("rm -r -f ./ArbolPruebas/ArbolborrarClaveEstaEnPadreQueEsRaiz*");
	Arbol arbol("./ArbolPruebas/ArbolborrarClaveEstaEnPadreQueEsRaiz",
			&extractor, 4, 4);
	for (int i = 0; i < 20; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[7]);
	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[10],
			"tiene en la raiz la nueva clave mayor: 9");

}

void TestNewArbol::underBalanceo() {
	std::cout
			<< "---------------------------under + balancear con hermano--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolunderBalanceo*");
	Arbol arbol("./ArbolPruebas/ArbolunderBalanceo", &extractor, 4, 4);
	for (int i = 0; i < 10; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[1]);
	arbol.borrar(*elements[6]);

	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[0]
			== *clavesOrdenadas[5], "el arbol debería tener en el nodo 03: 5 ");
	assert(arbol.getRaiz()->getClaves()[1] == *clavesOrdenadas[4],
			"el arbol debería tener en la raiz un 4 ");
}

void TestNewArbol::mergeDerechoHoja() {
	std::cout
			<< "---------------------------under + balancear con hermano Derecho en hoja--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolmergeDerechoHoja*");
	Arbol arbol("./ArbolPruebas/ArbolmergeDerechoHoja", &extractor, 4, 4);
	for (int i = 0; i < 10; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[9]);
	arbol.borrar(*elements[0]);
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[1]
			== *clavesOrdenadas[8],
			"el arbol debería tener en el nodo 02 un 8 ");
	assert(arbol.get(arbol.getRaiz()->getPunteros()[2])->getClaves()[0]
			== *clavesOrdenadas[9],
			"el arbol debería tener en el nodo 03 un 9 ");
	assert(arbol.getRaiz()->getClaves()[1] == *clavesOrdenadas[8],
			"el arbol debería tener en la raiz un 8 ");
}

void TestNewArbol::mergeDerechoIzqHoja() {
	std::cout
			<< "---------------------------under + merge Derecho mas Izq en Hoja--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolmergeDerechoIzqHoja*");
	Arbol arbol("./ArbolPruebas/ArbolmergeDerechoIzqHoja", &extractor, 4, 4);
	for (int i = 0; i < 10; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[9]);
	arbol.borrar(*elements[6]);

	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[2],
			"el arbol tiene un 2 ");
	arbol.borrar(*elements[0]);
	assert(arbol.get(arbol.getRaiz()->getPunteros()[1])->getClaves()[0]
			== *clavesOrdenadas[8],
			"ahora tiene la hoja nro 2 un 8 en la primer posicion");
	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[3],
			"el arbol tiene un 3");
	assert(arbol.getRaiz()->getClaves().size() == 2, "el arbol tiene dos hijos");

}

void TestNewArbol::mergeDerDerHoja() {
	std::cout
			<< "---------------------------under + merge Derecho mas Izq en Hoja--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolmergeDerDerHoja*");
	Arbol arbol("./ArbolPruebas/ArbolmergeDerDerHoja", &extractor, 4, 4);
	for (int i = 0; i < 10; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[9]);
	std::cout << "AHORA BORRO EL 2" << std::endl;
	arbol.borrar(*elements[5]);
	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[5],
			"el arbol tiene un 5 ");
	assert(arbol.getRaiz()->getClaves()[1] == *clavesOrdenadas[10],
			"el arbol tiene un 10 ");
}

void TestNewArbol::dosNoMergean() {
	std::cout
			<< "---------------------------dosNoMergean en hoja--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArboldosNoMergean*");
	Arbol arbol("./ArbolPruebas/ArboldosNoMergean", &extractor, 4, 4);
	for (int i = 0; i < 6; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[3]);
	arbol.borrar(*elements[4]);
	arbol.borrar(*elements[0]);

	assert(arbol.getRaiz()->getTipo() == 'H', "el arbol tiene un nodo ");
}

void TestNewArbol::IntUnderMergeDer() {
	std::cout
			<< "---------------------------Interno en Under Merge Der--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolIntUnderMergeDer*");
	Arbol arbol("./ArbolPruebas/ArbolIntUnderMergeDer", &extractor, 4, 4);
	for (int i = 0; i < 13; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.insertar(*elements[20]);
	arbol.insertar(*elements[16]);
	arbol.insertar(*elements[17]);
	Elemento elemento(Key(new ClaveInt(22)), 22);
	arbol.insertar(elemento);
	Elemento elemento2(Key(new ClaveInt(21)), 21);
	arbol.insertar(elemento2);
	arbol.insertar(*elements[18]);
	arbol.borrar(*elements[10]);
	arbol.borrar(*elements[2]);
	arbol.insertar(*elements[21]);
	arbol.insertar(*elements[19]);
	arbol.insertar(*elements[15]);
	arbol.borrar(*elements[3]);
	arbol.borrar(*elements[19]);
	arbol.visualizar();
	std::cout
			<< "en el test, ya voy a underflow, mirar:----------------------------"
			<< std::endl;
	arbol.visualizar();
	arbol.borrar(*elements[5]);
	arbol.visualizar();
	std::cout << "luego de terminar de repartir:----------------------------"
			<< std::endl;

	assert(arbol.getRaiz()->getClaves()[0] == *clavesOrdenadas[19],
			"el arbol tiene un 19 ");

}

void TestNewArbol::IntUnderMergeIzq() {
	std::cout
			<< "---------------------------IntUnderMerge con Izq--------------------------"
			<< std::endl;
	system("rm -r -f ./ArbolPruebas/ArbolIntUnderMergeIzq*");
	Arbol arbol("./ArbolPruebas/ArbolIntUnderMergeIzq", &extractor, 4, 4);
	for (int i = 0; i < 20; ++i) {
		arbol.insertar(*elements[i]);
	}
	arbol.borrar(*elements[11]);
	arbol.borrar(*elements[12]);
	arbol.borrar(*elements[13]);
	arbol.borrar(*elements[18]);
}
